<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of BATypedEventCooker
 *
 * @author I062261
 */
abstract class BATypedEventCooker extends BAEventCooker {

    const Type_all = 'all_type';

    protected abstract function getTypeOwnerName();

    protected abstract function getOwnerTableName();

    public abstract function onShowMemberHome();

    public abstract function onShowCustomerHome();

    public abstract function onShowAdminHome();

    protected function getTreeTable($type = NULL) {
        $treeTableName = $this->getOwnerTableName();
        if ($type == self::Type_all) {
            return new BASheet($treeTableName, BTreeTable::All_Owner);
        } else {
            $oType = NULL;
            if ($type == NULL) {
                $oType = $this->getCurrentType();
            } else {
                $oType = $this->getType($type);
            }
            if ($oType != NULL) {
                return new BASheet($treeTableName, $oType);
            }
        }
    }

    public function addType($typeData, $typeId = NULL) {

        $typeName = NULL;
        $typeAlias = NULL;

        if (is_array($typeData)) {

            if (count($typeData) == 2) {
                $typeName = reset($typeData);
                $typeAlias = end($typeData);
            }
            if (isset($typeData['id'])) {
                $typeId = $typeData['id'];
            }
            if (isset($typeData['typeId'])) {
                $typeId = $typeData['typeId'];
            }
            if (isset($typeData['name'])) {
                $typeName = $typeData['name'];
                unset($typeData['name']);
            }
            if (isset($typeData['alias'])) {
                $typeAlias = $typeData['alias'];
                unset($typeData['alias']);
            }
        }

        if ($typeName != NULL && $typeAlias == NULL) {
            $typeAlias = $typeName;
        }

        $type = NULL;
        if ($typeName != NULL && $typeAlias != NULL) {
            if (is_numeric($typeId) && $typeId != NULL) {
                $type = new BACategory($typeId);
                $type->name = $typeName;
                $type->value = $typeAlias;
                $type->save();
            } else {
                $typeRoot = $this->getTypeRoot();
                $type = $typeRoot->addChild(array('name' => $typeName, 'value' => $typeAlias));
            }
        }

        if ($type instanceof BACategory) {
            foreach ($typeData as $name => $value) {
                $this->addTypeAttribute($name, $value, $type);
            }
        }

        return FALSE;
    }

    public function deleteType($typeData) {
        $type = $this->getType($typeData);
        if ($type instanceof BACategory) {
            $parent = $type->getParent();
            if ($parent instanceof BACategory) {
                return $parent->removeChild($type);
            }
        }
    }

    public function getTypeList($format = 'objectList', $parentType = NULL, $recursive = FALSE) {

        if ($parentType == NULL) {
            $parentType = $this->getTypeRoot();
        } else {
            $parentType = $this->getType($parentType);
        }

        if ($parentType instanceof BACategory) {
            $list = $parentType->getChildrenAsLeaf();
            if (strtolower($format) == 'aliaslist') {
                $aList = array();
                foreach ($list as $type) {
                    $aList[$type->getName()] = $type->getValue();
                }
                return $aList;
            }
            if (strtolower($format) == 'objectlist') {
                return $list;
            }
        }
        return array();
    }

    //put your code here
    public function getType($typeData) {
        $typeName = NULL;
        if (is_numeric($typeData)) {
            $typeId = $typeData;
            return new BACategory($typeId);
        }
        if ($typeData instanceof BACategory) {
            return $typeData;
        }
        if (is_string($typeData)) {
            $typeName = $typeData;
        }
        if (is_array($typeData)) {
            if (isset($typeData['typeName'])) {
                $typeName = $typeData['typeName'];
            }
            if (isset($typeData['name'])) {
                $typeName = $typeData['name'];
            }
        }
        if ($typeName != NULL) {
            $typeRoot = $this->getTypeRoot();
            $typeRootName = $typeRoot->getName();
            if (strpos($typeName, $typeRootName) !== FALSE) {
                return $typeRoot->getChild($typeName);
            } else {
                $typeName = str_replace($typeRootName . '.', $typeName, '');
                return $typeRoot->getChild($typeName);
            }
        }
        return FALSE;
    }

    public function getCurrentType() {
        $typeId = $this->activeLink->getLinkVariable('typeId');
        $rootTypeName = $this->getTypeRoot()->getName();

        if ($typeId === 0 || $typeId === '0' || $typeId < 0) {
            return NULL;
        }

        $type = $this->getType($typeId);
        if ($type != NULL) {
            Blyn::app()->getActiveOperation()->addContextVariable($rootTypeName . 'Id', $typeId);
            return $type;
        } else {
            $typeId = Blyn::app()->getActiveOperation()->getContextVariable($rootTypeName . 'Id');
            $type = $this->getType($typeId);
            return $type;
        }
    }

    public function getTypeAlias($typeData) {
        $type = $this->getType($typeData);
        if ($type instanceof BACategory) {
            return $type->getValue();
        }
    }

    protected function getTypeRoot() {

        $ownerName = $this->getTypeOwnerName();
        if (is_string($ownerName) && $ownerName != NULL) {
            $typeRoot = BACategory::getMyRootNode()->getChild($ownerName . 'Type');
            if ($typeRoot == NULL) {
                $typeRoot = BACategory::getMyRootNode()->addChild($ownerName . 'Type');
            }
            return $typeRoot;
        }
        return NULL;
    }

    public function addTypeAttribute($attributeName, $attributeValue, $typeData = NULL, $data = NULL) {

        $type = NULL;
        if ($typeData == NULL) {
            $type = $this->getCurrentType();
        } else {
            $type = $this->getType($typeData);
        }
        if ($type instanceof BACategory) {
            return $type->addAttribute($attributeName, $attributeValue, array('attributeClass' => 'BAAttribute'));
        }
        return FALSE;
    }

    public function getTypeAttribute($name, $typeData = NULL) {
        $type = NULL;
        if ($typeData == NULL) {
            $type = $this->getCurrentType();
        } else {
            $type = $this->getType($typeData);
        }
        if ($type instanceof BACategory) {
            return $type->getAttribute($attributeName, array('attributeClass' => 'BAAttribute'));
        }
        return FALSE;
    }

    public function getTypeAllAttributes($format = 'attributeList', $type = NULL) {
        $type = NULL;
        if ($typeData == NULL) {
            $type = $this->getCurrentType();
        } else {
            $type = $this->getType($typeData);
        }
        $attributes = array();
        if ($type instanceof BACategory) {
            $attributes = $type->getAttributes(array('attributeClass' => 'BAAttribute'));
        }
        $format = strtolower(trim($format));
        if ($format == 'arraylist') {
            $aList = array();
            foreach ($attributes as $attr) {
                $aList[$attr->name] = $attr->value;
            }
            return $aList;
        }
        return $attributes;
    }

    public function onAddType() {

        $postData = $this->postManager->populatePostDataByIndex($this->postData, 'add_type');
        $model = BAModelCooker::getDynamicModel($postData, 'add_type');

        $inputError = FALSE;
        $inputError = $this->checkInputError($postData, $model);

        if (!$inputError) {
            $this->addType($postData);
            $this->onShowTypeList();
        } else {
            $this->onShowAddType($model);
        }
    }

    public function onDeleteType() {
        
    }

    public function onShowAddType($model = NULL) {

        $type = $this->getCurrentType();

        $typeAttributes = array();
        $typeAttributes['name'] = NULL;
        $typeAttributes['alias'] = NULL;

        if ($type instanceof BEntity) {//初始化数据
            $typeAttributes = $type->getAttributes();
            $attrData = BAAttributeCooker::getAttributesInArray($attributes);
            $typeAttributes+=$attrData;
        }

        $modelCooker = new BAModelCooker();
        if ($model == NULL) {
            $model = $modelCooker->getDynamicModel($typeAttributes, 'add_type');
        }

        $fieldList = $modelCooker->getDynamicModelFieldList($typeAttributes, 'add_type');

        foreach ($fieldList as $name => $field) {
            if (!isset($model->$field)) {
                $model->addField($field);
            }
        }

        $viewData = array();
        $viewData['model'] = $model;
        $viewData+=$fieldList;
        $viewData['viewData'] = $viewData;
        $viewData['cooker'] = get_class($this);

        $this->updateControl->addRenderView('addType', 'type_add', $viewData);
    }

    public function onShowTypeList($control = NULL) {
        $operationName = Blyn::app()->getActiveOperation()->getName();
        $typeList = $this->getTypeList();
        if(!$control instanceof BUIControl){
            $control = $this->updateControl;
        }
        $control->addRenderView('listType', 'type_list_' . $operationName, array(
            'typeList' => $typeList,
            'cooker' => get_class($this)
        ));
    }

    public function checkInputError($typeData, &$model) {
        $type = $this->getType($typeData);
        if ($type == NULL) {
            $type = $this->getCurrentType();
        }
        $isError = FALSE;
        if ($type == NULL && $model instanceof BDynamicFormModel) {
            if (is_array($typeData)) {
                if (!isset($typeData['name'])) {
                    $model->addError('media_name_add_type', 'must input name');
                    $isError = TRUE;
                }
                if (!isset($typeData['alias'])) {
                    $model->addError('media_alias_add_type', 'must input alias');
                    $isError = TRUE;
                }
            }
        }

        return $isError;
    }

}
